package com.xiaoxing.yunshu.mvp.ui.util;

import android.annotation.SuppressLint;
import android.app.KeyguardManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.PowerManager;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

/**
 * @ProjectName: Xiaoxing_YunShu_20200206_HeZe
 * @Package: com.xiaoxing.yunshu.mvp.ui.util
 * @ClassName: UPowerManager
 * @Description: java类作用描述
 * @Author: 小星
 * @CreateDate: 2020/7/9 0009 13:47
 * @UpdateUser: 更新者：
 * @UpdateDate: 2020/7/9 0009 13:47
 * @UpdateRemark: 更新说明：
 * @Version: 1.0
 */
public class UPowerManager {
    /**
     * 上下文
     */
    private Context context;
    /**
     * 回调接口
     */
    private ScreenStatusCallback callback;
    /**
     * 电源管理
     */
    private PowerManager pm;
    /**
     * 亮屏息屏操作对象
     */
    private PowerManager.WakeLock wakeLock;
    /**
     * 键盘锁管理器对象
     */
    private KeyguardManager km;
    /**
     * 屏幕监听器
     */
    private ScreenBroadcastReceiver receiver;
    /**
     * 当前使用的电源锁类型
     */
    private int curLevelAndFlags = -1;

    /**
     * @param context  {@link Context} can not be null
     * @param callback {@link ScreenStatusCallback} can be null
     */
    public UPowerManager(@NonNull Context context, @Nullable ScreenStatusCallback callback) {
        this.context = context;
        if (pm == null) {
            pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        }
        if (km == null) {
            km = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
        }
        //监听屏幕状态
        if (callback != null) {
            this.callback = callback;
            registerReceiver();
        }
    }

    /**
     * 注册屏幕监听广播
     */
    private void registerReceiver() {
        if (receiver == null) {
            receiver = new ScreenBroadcastReceiver();
        }
        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_SCREEN_ON);
        filter.addAction(Intent.ACTION_SCREEN_OFF);
        filter.addAction(Intent.ACTION_USER_PRESENT);
        context.registerReceiver(receiver, filter);
    }


    /**
     * 息屏
     * 传递的参数可以一个, 大部分可以组合使用(使用|隔开)
     * 与{@link UPowerManager#setScreenOn(int)} 成对使用
     *
     * @param levelAndFlags {@link PowerManager#FULL_WAKE_LOCK}
     *                      {@link PowerManager#ON_AFTER_RELEASE}
     *                      {@link PowerManager#PARTIAL_WAKE_LOCK}
     *                      {@link PowerManager#SCREEN_DIM_WAKE_LOCK}
     *                      {@link PowerManager#ACQUIRE_CAUSES_WAKEUP}
     *                      {@link PowerManager#SCREEN_BRIGHT_WAKE_LOCK}
     *                      {@link PowerManager#PROXIMITY_SCREEN_OFF_WAKE_LOCK}
     *                      {@link PowerManager#RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY}
     */
    @SuppressLint("InvalidWakeLockTag")
    public void setScreenOff(int levelAndFlags) throws ArgumentNotFormatLastException {
        if (curLevelAndFlags != -1) {
            if (curLevelAndFlags != levelAndFlags) {
                throw new ArgumentNotFormatLastException("与上一次传递进来的参数不一致");
            }
        }
        curLevelAndFlags = levelAndFlags;
        if (wakeLock == null) {
            wakeLock = pm.newWakeLock(levelAndFlags, "Screen");
        }
        wakeLock.acquire();
        //wakeLock.acquire(2000); // 延迟2秒后获取电源锁
    }

    /**
     * 亮屏
     * 与{@link UPowerManager#setScreenOff(int)} 成对使用
     * 传递的参数可以一个, 大部分可以组合使用(使用|隔开)
     *
     * @param levelAndFlags {@link PowerManager#FULL_WAKE_LOCK}
     *                      {@link PowerManager#ON_AFTER_RELEASE}
     *                      {@link PowerManager#PARTIAL_WAKE_LOCK}
     *                      {@link PowerManager#SCREEN_DIM_WAKE_LOCK}
     *                      {@link PowerManager#ACQUIRE_CAUSES_WAKEUP}
     *                      {@link PowerManager#SCREEN_BRIGHT_WAKE_LOCK}
     *                      {@link PowerManager#PROXIMITY_SCREEN_OFF_WAKE_LOCK}
     *                      {@link PowerManager#RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY}
     */
    @SuppressLint("InvalidWakeLockTag")
    public void setScreenOn(int levelAndFlags) throws ArgumentNotFormatLastException {
        if (curLevelAndFlags != -1) {
            if (curLevelAndFlags != levelAndFlags) {
                throw new ArgumentNotFormatLastException("与上一次传递进来的参数不一致");
            }
        }
        curLevelAndFlags = levelAndFlags;
        if (wakeLock == null) {
            wakeLock = pm.newWakeLock(levelAndFlags, "Screen");
        }
        wakeLock.setReferenceCounted(false);
        wakeLock.release();
        wakeLock = null;
    }

    /**
     * 息屏(靠近传感器)
     * 与{@link UPowerManager#setScreenOn()}成对使用
     */
    @SuppressLint("InvalidWakeLockTag")
    public void setScreenOff() {
        if (wakeLock == null) {
            wakeLock = pm.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, "Screen");
        }
        wakeLock.acquire();
    }

    /**
     * 亮屏(远离传感器)
     * 与{@link UPowerManager#setScreenOff()}成对使用
     */
    @SuppressLint("InvalidWakeLockTag")
    public void setScreenOn() {
        if (wakeLock == null) {
            wakeLock = pm.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, "Screen");
        }
        wakeLock.setReferenceCounted(false);
        wakeLock.release();
        wakeLock = null;
    }

    /**
     * 释放资源: 如果传入了回调接口, 必须调用此方法解绑广播
     */
    public void release() {
        if (context != null && receiver != null) {
            context.unregisterReceiver(receiver);
        }
        if (wakeLock != null) {
            wakeLock.release();
            wakeLock = null;
        }
    }

    /**
     * 检查屏幕状态:
     *
     * @return true: 亮屏 false: 息屏
     */
    private boolean checkScreen() {
        return pm.isScreenOn();
    }

    /**
     * 检查锁屏状态
     *
     * @return true: 有锁屏, false: 无锁屏
     */
    private boolean isScreenLock() {
        return km.inKeyguardRestrictedInputMode();
    }

    /**
     * 屏幕状态回调接口
     *
     * @author tgvincent
     * @version 1.0
     */
    public interface ScreenStatusCallback {
        /**
         * 亮屏
         */
        void onScreenOn();

        /**
         * 息屏
         */
        void onScreenOff();

        /**
         * 解锁
         */
        void onUserPresent();
    }

    /**
     * 屏幕状态广播接收器
     *
     * @author tgvincent
     * @version 1.1
     */
    class ScreenBroadcastReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            switch (action) {
                case Intent.ACTION_SCREEN_ON://开屏
                    callback.onScreenOn();
                    break;
                case Intent.ACTION_SCREEN_OFF://锁屏
                    callback.onScreenOff();
                    break;
                case Intent.ACTION_USER_PRESENT://解锁
                    callback.onUserPresent();
                    break;
            }
        }
    }

    /**
     * 自定义异常
     */
    public class ArgumentNotFormatLastException extends Exception {
        public ArgumentNotFormatLastException(String msg) {
            super(msg);
        }
    }
}
